// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __VULKANMAIN_HPP__
#define __VULKANMAIN_HPP__

#include "android_native_app_glue.h"
#include "vulkan_wrapper.h"

#include <cassert>
#include <cstring>
#include <vector>

// Global Variables ...
struct VulkanDeviceInfo {
    VkPhysicalDevice gpuDevice_;
    VkDevice logicalDevice_;
    uint32_t queueFamilyIndex_;
    VkQueue queue_;
};

struct VulkanSwapchainInfo {
    VkSwapchainKHR swapchain_;
    uint32_t length_;

    VkExtent2D displaySize_;
    VkFormat displayFormat_;

    // array of frame buffers and views
    std::vector<VkImage> displayImages_;
    std::vector<VkImageView> displayViews_;
    std::vector<VkFramebuffer> framebuffers_;
};

struct VulkanDepthBufferInfo {
    VkImage image_;
    VkImageView imageView_;
    VkFormat format_;
    VkDeviceMemory memory_;
};

struct VulkanBufferInfo{
    VkBuffer buffer_;
    VkDeviceMemory memory_;
    void * pData;
};

struct VulkanPipelineInfo {
    VkPipelineLayout layout_;
    VkPipelineCache cache_;
    VkPipeline pipeline_;
};

struct VulkanDescriptorInfo{
    VkDescriptorPool pool_;
    VkDescriptorSetLayout layout_;
    VkDescriptorSet set_;
};

struct VulkanCommandInfo{
    VkCommandPool pool_;
    VkCommandBuffer *buffer_;
    uint32_t length_;
};

struct VulkanInfo{
    bool initialized_;

    VkInstance instance_;
    VulkanDeviceInfo device;
    VulkanSwapchainInfo swapchain;
    VulkanCommandInfo command;
    VulkanDepthBufferInfo depth;
    VulkanBufferInfo uniform;
    VulkanBufferInfo vertex;
    VulkanPipelineInfo pipeline;
    VulkanDescriptorInfo descriptor;
    VkRenderPass renderPass_;
    VkSemaphore semaphore_;
    VkFence fence_;
    VkShaderModule vertexShader_, fragmentShader_;
    VkViewport viewport;
    VkRect2D scissor;

};


// Initialize vulkan device context
// after return, vulkan is ready to draw
bool InitializeVulkan(android_app *app);

// delete vulkan device context when application goes away
void DeleteVulkan(void);

// Check if vulkan is ready to draw
bool IsVulkanReady(void);

// Ask Vulkan to Render a frame
bool VulkanDrawFrame(void);

// create Vulkan resource
void CreateVulkanInstance(ANativeWindow *);
void CreateVulkanDevice();
void CreateCommandBuffer();
void CreateSwapChain(ANativeWindow *);
void CreateDepthBuffer();
bool CreateUniformBuffer();
void CreatePipeLineLayout();
void CreateDescriptorSet();
void CreateRenderPass();
void CreateShader();
void CreateFrameBuffers();
bool CreateVertexBuffers();
void CreatePipeline(void);
void RecordCommands(uint32_t);

// clean up

#endif // __VULKANMAIN_HPP__


